package cn.dakaqi.pingan.util;

import cn.dakaqi.pingan.entities.InAccount;
import cn.dakaqi.services.PinganNumberService;
import cn.dakaqi.utils.http.HttpInvoker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author chunyang on 2016/3/22.
 * 平安银行银企直连接口 企业单笔资金划转
 */
@Component
@Transactional
@Slf4j
public class PayTools
{
    @Autowired
    PinganNumberService pinganNumberService;
    String type = "P";
    String OutAcctName = "上海悠活网络科技有限公司";
    String InAcctBankName = "中国银行上海市虹梅路支行";
    String OutAcctNo = "11015100817002";
    String CcyCode = "RMB";

    /**
     * 3.14 查询账户历史交易明细[4013]
     * 注意：4013接口上送的页码起始为1，与4008的起始为0不同。
     * 此历史明细查询的时间跨度必须为12月内，支持3年内的查询。
     */
    public void queryAllTradeHistory(String account, String beginDate, String endDate, String PageNo)
    {
        try
        {
//            account = "11000593657501";
//            beginDate = "20160101";
//            endDate = "20161231";
//            PageNo = "000001";
            String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Result><AcctNo>" + account + "</AcctNo><CcyCode>RMB</CcyCode><BeginDate>" + beginDate + "</BeginDate><EndDate>" + endDate + "</EndDate><PageNo>" + PageNo + "</PageNo><Reserve></Reserve></Result>";
            String sn = pinganNumberService.createNO(type);
            String head = MessageHead.A00101(xml, sn, "4013  ", PingAnUtil.shopNO);
            log.info(head.getBytes("UTF-8").length + "====>" + head);
            log.info(head + xml);
            String retValue = HttpInvoker.httpPostXML(PingAnUtil.B2BiUrl, head + xml);
            log.info("【查询账户历史交易明细 4013】 返回信息:" + retValue);
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     * 3.3 企业当日交易明细查询[4008]
     * 当日明细目前支持两种查询方式：按页码查询和按日志号偏移量查询。
     * 1、按页码查询：
     * 此接口不支持跳页查询明细，必须从0开始，按返回的页码递增上送页码，若跳跃上送页码，返回请求错误。
     * 不支持直接从非第一页开始查询，不支持重复查询非第一页的内容，重新查询必须从页码0开始。
     * 注意：4013接口上送的页码起始为1，与4008的起始为0不同。
     * 2、按日志号偏移量查询【推荐】：
     * 用户上送日志号JournalNo和偏移量LogCount，首次查询上送0，下次查询上送最后页返回的输出值。支持对任意页重复查询，但不支持增量查询。
     */
    public void queryTodayTradeHistory(String account)
    {
        try
        {
            String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Result><AcctNo>" + account + "</AcctNo><CcyCode>RMB</CcyCode><PageNo>0</PageNo></Result>";
            String sn = pinganNumberService.createNO(type);
            String head = MessageHead.A00101(xml, sn, "4008  ", PingAnUtil.shopNO);
            log.info(head.getBytes("UTF-8").length + "====>" + head);
            log.info(head + xml);
            String retValue = HttpInvoker.httpPostXML(PingAnUtil.B2BiUrl, head + xml);
            log.info("【企业当日交易明细查询 4008】 返回信息:" + retValue);
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     * 3.2 企业账户余额查询 [4001]
     * 此接口适应银行所有币种的活期账户的余额查询，其中的可用余额只包含自身的资金状况，而不包括集团内部的资金池。
     * 账面余额，也只是自身账号的账面金额。
     * 如果需要查询集团现金管理子账户的可用余额，需要调用“现金管理子账户余额查询[4059]”接口。
     */
    public void queryBalance(String account)
    {
        try
        {
            String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Result><Account>" + account + "</Account><CcyType>C</CcyType><CcyCode>RMB</CcyCode></Result>";
            String sn = pinganNumberService.createNO(type);
            String head = MessageHead.A00101(xml, sn, "4001  ", PingAnUtil.shopNO);
            log.info(head.getBytes("UTF-8").length + "====>" + head);
            log.info(head + xml);
            String retValue = HttpInvoker.httpPostXML(PingAnUtil.B2BiUrl, head + xml);
            log.info("【企业账户余额查询 4001】 返回信息:" + retValue);
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     * 企业单笔资金划转 [4004]
     * @param inAccount
     * 本接口实时返回的000000只表示受理成功，不代表转账成功；返回非000000也不能置失败，可能代表通讯异常。
     */
    public String payMoney(InAccount inAccount)
    {

        try
        {
            //String OutAcctName = "平安测试保险";
            //String OutAcctNo = "11000593657501";
            //String CcyCode = "RMB";
            //InAcctBankName = "平安测试热能工程有限公司";
            //InAcctNo = "11014820381007";
            //InAcctName = "平安测试热能工程有限公司";
            //TranAmount = "1.00";
            String sn = pinganNumberService.createNO(type);
            String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Result><ThirdVoucher>" + sn + "</ThirdVoucher><FrontLogNo></FrontLogNo><CcyCode>" + CcyCode + "</CcyCode><OutAcctName>" + OutAcctName + "</OutAcctName><OutAcctNo>" + OutAcctNo + "</OutAcctNo><InAcctBankName>" + InAcctBankName + "</InAcctBankName><InAcctNo>" + inAccount.getInAcctNo() + "</InAcctNo><InAcctName>" + inAccount.getInAcctName() + "</InAcctName><TranAmount>" + inAccount.getTranAmount() + "</TranAmount><UnionFlag>1</UnionFlag><AddrFlag>2</AddrFlag><Fee1></Fee1><Fee2></Fee2></Result>";
            String head = MessageHead.A00101(xml, sn, "4004  ", PingAnUtil.shopNO);
            //log.info(head.getBytes("UTF-8").length + "====>" + head);
            log.info(head + xml);
            String retValue = HttpInvoker.httpPostXML(PingAnUtil.B2BiUrl, head + xml);
            log.info("【企业单笔资金划转 4004】返回信息:" + retValue);
            return retValue;
        } catch (Exception e)
        {
            e.printStackTrace();
            log.error(e.getMessage());
        }
        return null;
    }
    /**
     * 3.10 单笔转账指令查询[4005]
     * @param OrigThirdVoucher
     * @param OrigFrontLogNo
     */
    public void querySingleTradeResult(String OrigThirdVoucher, String OrigFrontLogNo)
    {
        try
        {
            String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Result><OrigThirdLogNo></OrigThirdLogNo><OrigThirdVoucher>" + OrigThirdVoucher + "</OrigThirdVoucher><OrigFrontLogNo>" + OrigFrontLogNo + "</OrigFrontLogNo></Result>";
            String sn = pinganNumberService.createNO(type);
            String head = MessageHead.A00101(xml, sn, "4005  ", PingAnUtil.shopNO);
            log.info(head.getBytes("UTF-8").length + "====>" + head);
            log.info(head + xml);
            String retValue = HttpInvoker.httpPostXML(PingAnUtil.B2BiUrl, head + xml);
            log.info("【单笔转账指令查询 4005】 返回信息:" + retValue);
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     * 3.7 企业大批量资金划转[4018]
     * 此转账接口只返回银行受理成功，转账结果必须调用4015接口查询。
     * @param inAccounts
     */
    public String multiAccounts4018(String sn,String type,List<InAccount> inAccounts)
    {
        String result = null;
        try
        {
            String xml4Head = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Result>" +
                    "<ThirdVoucher>" + sn + "</ThirdVoucher>" +
                    "<totalCts>" + inAccounts.size() + "</totalCts>" +
                    "<totalAmt>" + inAccounts.size() + ".00</totalAmt>" +
                    "<BatchSummary/>" +
                    "<BSysFlag>N</BSysFlag>" +
                    "<CcyCode>" + this.CcyCode + "</CcyCode>" +
                    "<OutAcctNo>" + this.OutAcctNo + "</OutAcctNo>" +
                    "<OutAcctName>" + this.OutAcctName + "</OutAcctName>" +
                    "<OutAcctAddr/>" +
                    "<PayType/>" +
                    "<BizFlag1/>" +
                    "<BookingDate/>";

            String xml4End = "</Result>";

            String xml4Body = "";

            for (InAccount inAccount : inAccounts)
            {
                String tempBody = "<HOResultSet4018R><SThirdVoucher>" + pinganNumberService.createNO(type) + "</SThirdVoucher>" +
                        "<CstInnerFlowNo/>" +
                        "<InAcctBankNode/>" +
                        "<InAcctRecCode/>" +
                        "<InAcctNo>" + inAccount.getInAcctNo() + "</InAcctNo>" +
                        "<InAcctName>" + inAccount.getInAcctName() + "</InAcctName>" +
                        "<InAcctBankName>" + inAccount.getInAcctBankName() + "</InAcctBankName>" +
                        "<InAcctProvinceCode/>" +
                        "<InAcctCityName/>" +
                        "<TranAmount>" + inAccount.getTranAmount() + "</TranAmount>" +
                        "<UseEx>开户成功</UseEx>" +
                        "<UnionFlag>1</UnionFlag>" +
                        "<AddrFlag>2</AddrFlag>" +
                        "<MainAcctNo/></HOResultSet4018R>";
                xml4Body = xml4Body + tempBody;
            }
            String xml = xml4Head + xml4Body + xml4End;
            log.info(xml);
            String head = MessageHead.A00101(xml, sn, "4018  ", PingAnUtil.shopNO);
            //log.info(head.getBytes("UTF-8").length + "====>" + head);
            log.info(head + xml);
            String retValue = HttpInvoker.httpPostXML(PingAnUtil.B2BiUrl, head + xml);
            log.info("【4018 企业批量资金划转返回信息】" + retValue);
            String resultXML = retValue.split("000001RSA-SHA1    00000000000")[1];
            log.info("【4018 去除头信息后】" + resultXML);
            result = ParseXML.thirdVoucher(resultXML);
            log.info("【4018 批量转账凭证号】" + result);
        } catch (Exception e)
        {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 3.6 企业批量实时资金划转[4014]
     * 此接口实时返回转账结果，笔数限制不大于10，可使用4015查询转账结果。若接受返回超时，则需要使用4015查询结果。
     * @param inAccounts
     */
    public String multiAccounts4014(List<InAccount> inAccounts)
    {
        try
        {
            String sn = pinganNumberService.createNO(type);
            String xml4Head = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Result>" +
                    "<ThirdVoucher>" + sn + "</ThirdVoucher>" +
                    "<totalCts>" + inAccounts.size() + "</totalCts>" +
                    "<totalAmt>" + inAccounts.size() + ".00</totalAmt>";
            String xml4End = "</Result>";
            String xml4Body = "";

            for (InAccount inAccount : inAccounts)
            {
                String tempBody = "<HOResultSet4014R>" +
                        "<CcyCode>RMB</CcyCode>" +
                        "<OutAcctNo>" + this.OutAcctNo + "</OutAcctNo>" +
                        "<OutAcctName>" + this.OutAcctName + "</OutAcctName>" +
                        "<OutAcctAddr/>" +
                        "<InAcctBankNode/>" +
                        "<InAcctRecCode/>" +
                        "<InAcctNo>" + inAccount.getInAcctNo() + "</InAcctNo>" +
                        "<InAcctName>" + inAccount.getInAcctName() + "</InAcctName>" +
                        "<InAcctBankName>" + inAccount.getInAcctBankName() + "</InAcctBankName>" +
                        "<TranAmount>" + inAccount.getTranAmount() + "</TranAmount>" +
                        "<AmountCode/>" +
                        "<UseEx>开户成功</UseEx>" +
                        "<UnionFlag>1</UnionFlag>" +
                        "<SysFlag/>" +
                        "<AddrFlag>2</AddrFlag>" +
                        "<MainAcctNo/>" +
                        "<Fee1></Fee1><Fee2></Fee2>" +
                        "</HOResultSet4014R>";
                xml4Body = xml4Body + tempBody;
            }
            String xml = xml4Head + xml4Body + xml4End;
            log.info(xml);
            String head = MessageHead.A00101(xml, sn, "4014  ", PingAnUtil.shopNO);
            log.info(head.getBytes("UTF-8").length + "====>" + head);
            log.info(head + xml);
            String retValue = HttpInvoker.httpPostXML(PingAnUtil.B2BiUrl, head + xml);
            log.info("【企业批量资金划转 4014】返回信息:" + retValue);
            return retValue;
        } catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }

    /**
     *3.11 批量转账指令查询[4015]
     * 报文头中的错误码和错误信息表示本次查询动作的处理结果，不表示转账指令的处理结果，需要解析Stt、Yhcljg来确定；
     * 只有在转账记录银行未收到的情况下，报文头报错：记录不存在。
     * 用于查询4014，4018，4034上送的批量转账结果信息。
     */
    public void query4015(String targetSN)
    {
        try
        {
            //String targetSN = "P2016090610310000004";
            String sn = pinganNumberService.createNO(type);
            String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" +
                    "<Result>" +
                    "<OrigThirdVoucher>"+targetSN+"</OrigThirdVoucher>" +
                    "</Result>";

            String head = MessageHead.A00101(xml, sn, "4015  ", PingAnUtil.shopNO);
            //log.info(head.getBytes("UTF-8").length + "====>" + head);
            log.info(head + xml);
            String retValue = HttpInvoker.httpPostXML(PingAnUtil.B2BiUrl, head + xml);
            log.info("【4015 企业批量资金划转 返回信息】" + retValue);
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}
